package org.itboys.product.service;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.itboys.commons.utils.io.FileUtils;
import org.itboys.dto.Category;
import org.itboys.framework.resource.ResourceHolder;
import org.itboys.mongodb.core.MongoDataSource;
import org.itboys.mongodb.service.BaseService;
import org.itboys.mongodb.utils.query.QueryParamUtils;
import org.itboys.oss.OssService;
import org.itboys.product.constant.ProductConstant;
import org.itboys.product.entity.ProductCategory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import org.mongodb.morphia.query.Query;
import com.google.common.collect.Lists;

/**
 * 分类
 * 
 * @author WangRan
 * 
 *         2015年8月22日
 */
@Service
public class ProductCategoryService extends BaseService<ProductCategory, Long> {

	private static final long serialVersionUID = 4695089665310198377L;

	@Resource(name = "productDS")
	private MongoDataSource ds;
	@Autowired
	private ResourceHolder resourceHolder;

	@Resource(name = "ossService")
	OssService productOssService;

	@Override
	protected MongoDataSource getMongoDataSource() {
		return ds;
	}

	@Override
	protected Class<ProductCategory> getEntityClass() {
		return ProductCategory.class;
	}

	/**
	 * 条件搜索 无分页
	 * 
	 * @param request
	 * @return
	 */
	public List<ProductCategory> list(HttpServletRequest request) {
		Map<String, Object> param = QueryParamUtils.builderQueryMap(request);
		
		Iterator<String> ite = param.keySet().iterator();
		Query<ProductCategory> query = ds.createQuery(getEntityClass()).filter("isDeleted", 0).order("-isRec,sort");
		while (ite.hasNext()) {
			String key = ite.next();
			Object value = param.get(key);
			query.filter(key, value);
		}
		List<ProductCategory> amList = query.asList();
		for (ProductCategory pc : amList) {
			pc.set_parentId(pc.getParentId());
		}
		return amList;
	}

	/**
	 * 修改或保存
	 * 
	 * @param productCategory
	 * @param tlogo
	 * @param tImage
	 * @return
	 */
	public boolean insert(ProductCategory productCategory, MultipartFile tlogo, MultipartFile tImage) {
		try {

			ProductCategory pc = null;
			if (productCategory.getId() != 0) {
				pc = getById(productCategory.getId());
			}

			if (tlogo != null && !tlogo.isEmpty() && tlogo.getSize() > 0) {
				String tlogoPath = productOssService.upload(tlogo.getInputStream(), ProductConstant.ImgPath.OSS_PATH);
				productCategory
						.setLogo(ProductConstant.OSS_URL_PREFIX + ProductConstant.ImgPath.OSS_PATH + "/" + tlogoPath);
			} /*
				 * else{ if(pc != null &&
				 * StringUtils.isNotBlank(pc.getLogo())){//如果之前已经存在图片 则保持不变
				 * productCategory.setLogo(pc.getLogo()); } }
				 */

			if (tImage != null && !tImage.isEmpty() && tImage.getSize() > 0) {
				String tImagePath = productOssService.upload(tImage.getInputStream(), ProductConstant.ImgPath.OSS_PATH);
				productCategory.setImage(tImagePath);
			} /*
				 * else{ if(pc != null &&
				 * StringUtils.isNotBlank(pc.getImage())){//如果之前已经存在图片 则保持不变
				 * productCategory.setImage(pc.getImage()); } }
				 */

			if (productCategory.getId() != 0) {
				productCategory.setLevel(pc.getLevel());
				productCategory.setFullIdPath(pc.getFullIdPath());
				if (productCategory.getParentId() == 0L) {// 最顶级的分类
					productCategory.setFullNamePath(
							ProductConstant.PATH_SPLIT + productCategory.getName() + ProductConstant.PATH_SPLIT);
				} else {
					productCategory.setFullNamePath(
							pc.getFullNamePath() + productCategory.getName() + ProductConstant.PATH_SPLIT);
				}
                if (StringUtils.isBlank(productCategory.getLogo()) && StringUtils.isNoneBlank(pc.getLogo())) {
                    productCategory.setLogo(pc.getLogo());
                }
				update(productCategory);
			} else {
				if (productCategory.getParentId() == 0L) {// 最顶级的分类
					productCategory.setFullNamePath(
							ProductConstant.PATH_SPLIT + productCategory.getName() + ProductConstant.PATH_SPLIT);
					productCategory.setLevel(1);
					save(productCategory);
					productCategory.setFullIdPath(
							ProductConstant.PATH_SPLIT + productCategory.getId() + ProductConstant.PATH_SPLIT);
					update(productCategory);
				} else {// 子分类
					ProductCategory parent = getById(productCategory.getParentId());
					productCategory.setFullNamePath(
							parent.getFullNamePath() + productCategory.getName() + ProductConstant.PATH_SPLIT);
					productCategory.setLevel(parent.getLevel() + 1);
					save(productCategory);
					productCategory.setFullIdPath(
							parent.getFullIdPath() + productCategory.getId() + ProductConstant.PATH_SPLIT);
					update(productCategory);
				}
			}

			return true;
		} catch (Exception e) {
			logger.error("ProductCategoryService.insert error", e);
		}
		return false;
	}

	/**
	 * 删除
	 * 
	 * @param id
	 * @return
	 */
	public boolean dele(Long id) {
		try {
			delete(id);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("ProductCategoryService.dele error", e);
		}
		return false;
	}

	/**
	 * 获取所有的有效的顶级分类
	 * 
	 * @return
	 */
	public List<ProductCategory> getRootCategory() {
		return ds.createQuery(getEntityClass()).filter("status", 1).filter("isDeleted", 0).filter("parentId", 0)
				.order("sort").asList();
	}
	/**
	 * 获取普通商品顶级分类
	 * @return
	 */
	public List<ProductCategory> getProRootCategory() {
		return ds.createQuery(getEntityClass()).filter("type", 1).filter("status", 1).filter("isDeleted", 0).filter("parentId", 0)
				.order("sort").asList();
	}
	/**
	 * 根据parentCategoryId父类的ID获取平级的所有有效的分类
	 * 
	 * @param parentCategoryId
	 * @return
	 */
	public List<ProductCategory> getNextCategory(Long parentCategoryId) {
		return ds.createQuery(getEntityClass()).filter("status", 1).filter("isDeleted", 0)
				.filter("parentId", parentCategoryId).asList();
	}

	public Category[] getCategoryTree(Long sellerId, Integer type) {
		Map<String, Object> param = Maps.newHashMapWithExpectedSize(2);
		// 分类由总平台确定，所以这里不需要此条件
		// param.put("sellerId", sellerId);
        if (type != null) {
            param.put("type", type);
        }
		param.put("status", 1);
		List<ProductCategory> all = list(param);
		List<Category> roots = Lists.newArrayList();
		all.forEach(productCategory -> {
			if (productCategory.getParentId() == 0L) {
				roots.add(transform(productCategory));
			}
		});
		for (Category root : roots) {
			assembleCategory(all, root);
		}
		return roots.toArray(new Category[roots.size()]);
	}

	private void assembleCategory(List<ProductCategory> all, Category category) {
		for (ProductCategory productCategory : all) {
			if (productCategory.getParentId() != null && productCategory.getParentId().equals(category.getId())) {
				Category childCategory = transform(productCategory);
				category.getChildren().add(childCategory);
				assembleCategory(all, childCategory);
			}
		}
	}

	private Category transform(ProductCategory productCategory) {
		Category category = new Category();
		category.setId(productCategory.getId());
		category.setName(productCategory.getName());
		category.setLogo(productCategory.getLogo());
		category.setFullNamePath(productCategory.getFullNamePath());
		category.setLeaf(productCategory.isLeaf());
		return category;
	}

	public List<ProductCategory> getRecCats(Long parentCategoryId) {
		return ds.createQuery(getEntityClass()).filter("status", 1).filter("isDeleted", 0)
				.filter("parentId", parentCategoryId).filter("isRec", 1).limit(3).asList();
	}

	public List<ProductCategory> getNormalCats(Long parentCategoryId) {
		return ds.createQuery(getEntityClass()).filter("status", 1).filter("isDeleted", 0)
				.filter("parentId", parentCategoryId).filter("isRec", 0).asList();
	}

	public void doRecommend(Long id) {
		ProductCategory productCategory = getById(id);
		productCategory.setIsRec(1);
		update(productCategory);
		List<ProductCategory> cats = getMongoDataSource().createQuery(getEntityClass()).filter("isRec", 1)
				.filter("deleted", false).order("-ut").asList();
		if (cats.size() > 3) {
			cats = cats.subList(3, cats.size());
			for (ProductCategory cat : cats) {
				cat.setIsRec(0);
			}
			batchUpdate(cats);
		}
	}
	public void cancelRecommend(Long id) {
		ProductCategory productCategory = getById(id);
		productCategory.setIsRec(0);
		update(productCategory);
	}
}
